package org.jetbrains.plugins.scala.lang.typeInference.testInjectors

import com.intellij.psi.PsiManager
import org.jetbrains.plugins.scala.lang.psi.api.base.{ScInterpolatedStringLiteral, ScReference}
import org.jetbrains.plugins.scala.lang.psi.api.statements.ScFunction
import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiElementFactory
import org.jetbrains.plugins.scala.lang.psi.impl.base.InterpolatedStringMacroTypeProvider
import org.jetbrains.plugins.scala.lang.psi.types.result.TypeResult
import org.jetbrains.plugins.scala.lang.resolve.ScalaResolveResult

class SCL12987Injector extends InterpolatedStringMacroTypeProvider {
  /**
    * This method is used to decide whether an interpolated string expression is a macro and its type could be infered
    * by this plugin.
    *
    * @param ref invoked function on interpolated string
    * @return if this interpolated string expression is a macro and its type inference is handled by the plugin
    */
  override def handlesInterpolatedString(ref: ScReference): Boolean = ref.bind() match {
    case Some(ScalaResolveResult(fun: ScFunction, _)) if fun.name == "toType" => true
    case _ => false
  }

  /**
    * This method allows to infer a type for code generated by a macro that is invoked on an interpolated string.
    *
    * @param pat the interpolated string literal that will be transformed by a macro
    * @return The resulting type of the code generated by a macro
    */
  override def inferExpressionType(pat: ScInterpolatedStringLiteral): TypeResult = {
    val resultingType = pat.getStringParts.mkString.split(':').last
    ScalaPsiElementFactory
      .createTypeElementFromText(resultingType, pat)(pat)
      .`type`()
  }
}
